package com.boot.app.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.boot.app.base.domain.BaseRole;
import com.boot.app.base.domain.BaseUser;
import com.boot.app.base.domain.BaseUserRoleRelation;
import com.boot.app.base.dto.UserDTO;
import com.boot.app.base.mapper.BaseUserMapper;
import com.boot.app.base.service.IBaseUserAdditionService;
import com.boot.app.base.service.IBaseUserRoleRelationService;
import com.boot.app.base.service.IBaseUserService;
import com.boot.app.base.vo.UserInfo;
import com.boot.app.base.vo.UserVO;
import com.boot.exception.UnAuthenticationException;
import com.boot.util.SessionUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class BaseUserServiceImpl extends ServiceImpl<BaseUserMapper, BaseUser> implements IBaseUserService {

    private final BaseUserMapper mapper;

    private final IBaseUserAdditionService userAdditionService;

    private final IBaseUserRoleRelationService userRoleRelationService;

    private final SessionUtil sessionUtil;

    @Autowired
    public BaseUserServiceImpl(
        BaseUserMapper mapper,
        IBaseUserAdditionService userAdditionService,
        IBaseUserRoleRelationService userRoleRelationService,
        SessionUtil sessionUtil
    ){
        this.mapper = mapper;
        this.userAdditionService = userAdditionService;
        this.userRoleRelationService = userRoleRelationService;
        this.sessionUtil = sessionUtil;
    }

    @Override
    public BaseUser getByUsername(String username) {
        LambdaQueryWrapper<BaseUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BaseUser::getUsername, username);
        return mapper.selectOne(wrapper);
    }

    @Override
    public UserVO getUserVOById(long id) {
        return mapper.selectUserVOById(id);
    }

    @Override
    public Page<UserVO> pageUserVO(Page<UserVO> page, UserDTO userDto) {
        return mapper.selectUserVOPage(page, userDto);
    }

    @Override
    public BaseUser getUserByUsername(String username) {
        LambdaQueryWrapper<BaseUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BaseUser::getUsername, username);
        return mapper.selectOne(wrapper);
    }



    @Override
    public UserInfo fetchUserInfo() {
        UserVO userVO = getUserVOById(sessionUtil.getUserId());

        LambdaQueryWrapper<BaseUserRoleRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BaseUserRoleRelation::getUserId, userVO.getId());
        List<BaseUserRoleRelation> relations = userRoleRelationService.list(wrapper);

        List<BaseRole> roles = new ArrayList<>();
        for(BaseUserRoleRelation relation: relations){
            BaseRole role = new BaseRole();
            role.setId(relation.getRoleId());
            roles.add(role);
        }

        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userVO, userInfo);
        userInfo.setRoles(roles);
        return userInfo;
    }

    @Override
    @Transactional
    public void removeUserById(long id) {
        mapper.deleteById(id);
        userAdditionService.removeById(id);

        LambdaQueryWrapper<BaseUserRoleRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BaseUserRoleRelation::getUserId, id);
        userRoleRelationService.remove(wrapper);
    }

}
